package com.mju.service.impl;

import com.mju.dao.UserDao;
import com.mju.pojo.User;
import com.mju.service.IUserService;
import com.mju.service.ex.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.Date;
import java.util.UUID;

@Service
public class UserServiceImpl implements IUserService {
    // 获取DAO层的接口
    @Autowired
    private UserDao userDao;

    @Override
    public void registor(User user) {
        // 获取用户名
        String username = user.getUsername();
        // 根据该用户名，尝试获取数据库里的用户名
        User result = userDao.selectByName(username);
        if(result != null) {
            // 跑出异常
            throw new UsernameDuplicatedException("用户名被占用，请重新选一个。");
        }

        // 密码加密
        String oldPassword = user.getUserpassword();
        // 随机生成一个盐值，并将密码和盐值作为一个整体进行加密。
        String salt = UUID.randomUUID().toString().toUpperCase();
        String md5Password = getMd5Password(oldPassword, salt);
        user.setUserpassword(md5Password);
        // 补全，其余数据
        user.setIsDelete(0);
        user.setSalt(salt); // 一定要加入盐值
        // 补全：日志
        user.setCreatedUser(user.getUsername());
        user.setModifiedUser(user.getUsername());
        Date date = new Date();
        user.setCreatedTime(date);
        user.setModifiedTime(date);

        // 执行注册业务的逻辑
        int rows = userDao.insert(user);
        if(rows != 1) {
            throw new InsertException("在用户注册过程中，产生了未知的异常。");
        }

    }

    @Override
    public User login(String username, String password) {
        // 查询用户是否存在于数据库中，不存在，抛出异常。
        User result = userDao.selectByName(username);
        if(result == null) {
            throw new UsernameNotFoundException("该用户不存在");
        }

        // 检测用户的密码是否匹配
        String oldPassword = result.getUserpassword();
        String salt = result.getSalt();
        String newPassword = getMd5Password(password, salt);
        //System.out.println("newPasw: "+newPassword);
        if(!newPassword.equals(oldPassword)) {
            throw new PasswordNotMatchException("用户密码错误");
        }

        // 判断下该用户数据是否被删除
        if(result.getIsDelete() == 1) {
            throw new UsernameNotFoundException("该用户不存在");
        }

        // 封装需要返回的数据，供其他页面(通过session)显示
        // 目的：减少数据量
        User user = new User();
        user.setId(result.getId());
        user.setUsername(result.getUsername());
        user.setAvatar(result.getAvatar());
        return user;
    }

    @Override
    public void changePassword(Integer id, String username, String oldPassword, String newPassword) {
        // 根据uid，查询数据存不存在
        User result = userDao.selectById(id);
        // 数据不存在，或被管理员误删除了
        if(result == null || result.getIsDelete() == 1) {
            throw new UsernameNotFoundException("用户数据不存在");
        }
        // 对比下旧密码是否与数据库一致
        String oldMd5Password = getMd5Password(oldPassword, result.getSalt());
        if(!result.getUserpassword().equals(oldMd5Password)) {
            throw new PasswordNotMatchException("密码错误");
        }

        // 更新密码(盐值用原来的)
        String newMd5Password = getMd5Password(newPassword, result.getSalt());
        result.setUserpassword(newMd5Password);
        result.setModifiedUser(username);
        result.setModifiedTime(new Date());
        // 修改密码
        int rows = userDao.updateById(result);
        if(rows != 1) {
            throw new UpdateException("更新数据产生未知的异常");
        }


    }

    @Override
    public User getById(Integer id) {
        // 查询用户是否存在
        User result = userDao.selectById(id);
        if(result == null || result.getIsDelete() == 1) {
            throw new UsernameNotFoundException("用户数据不存在。");
        }
        // 封装个人资料需要的4个字段，返回回去，节省数据量
        User user = new User();
        user.setUsername(result.getUsername());
        user.setPhone(result.getPhone());
        user.setEmail(result.getEmail());
        user.setGender(result.getGender());
        user.setIsDelete(result.getIsDelete()); // 增加一个字段
        return user;
    }

    // 注意：
    //      1. id通过控制层的session里头的id给与
    //      2. user对象只有4个字段，springboot只会注入表单里的数据，需要手动添加id
    @Override
    public void changeInfo(Integer id, User user) {
        // 查询用户是否存在
        User result = userDao.selectById(id);
        if(result == null || result.getIsDelete() == 1) {
            throw new UsernameNotFoundException("用户数据不存在。");
        }
        user.setId(id); // 缺id，一定要补。
        user.setModifiedUser(user.getUsername());
        user.setModifiedTime(new Date());
        // 更新数据
        int rows = userDao.updateById(user);
        if(rows != 1) {
            throw new UpdateException("更新数据时，产生未知异常。");
        }
    }

    @Override
    public void changeAvatar(Integer id, String avatar, String username) {
        // 查询用户是否存在
        User result = userDao.selectById(id);
        if(result == null || result.getIsDelete() == 1) {
            throw new UsernameNotFoundException("用户数据不存在。");
        }
        // 更新头像数据、修改时间、修改人
        result.setAvatar(avatar);
        result.setModifiedUser(username);
        result.setModifiedTime(new Date());
        int rows = userDao.updateById(result);
        if(rows != 1) {
            throw new UpdateException("更新用户头像时，产生未知异常。");
        }
    }

    // 加密算法
    // 核心：盐值 + 密码 + 盐值
    private String getMd5Password(String password, String salt) {
        for (int i = 0; i < 3; i++) {
            password = DigestUtils.md5DigestAsHex((salt + password + salt).getBytes());
        }
        return password;
    }
}
